import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
import Icon from './video.svg';
import Command from "@ckeditor/ckeditor5-core/src/command";
import {
  Widget,
  toWidget
} from '@ckeditor/ckeditor5-widget';

import {
  ClassicEditor
} from '@ckeditor/ckeditor5-editor-classic';

let url = ''

 function toMediaWidget(viewElement, writer, label) {
  writer.setCustomProperty('uploadVideo', true, viewElement);
  return toWidget(viewElement, writer, { label });
}

class ExternalDataWidgetCommand extends Command {
  execute() {
    const editor = this.editor;
    const selection = editor.model.document.selection;
    const uploadFun = this.editor.config._config.uploadVideo.uploadFun
    editor.model.change(writer => {

      let input = document.createElement('input')
      input.style.display = 'none'
      input.type = 'file'
      input.accept = '.mp4'
      document.body.appendChild(input)
      input.click()
      input.onchange = (e) => {
        uploadFun(e.target.files[0]).then(res=>{
          url=res
          const externalWidget = writer.createElement(
            'uploadVideo', {
              ...Object.fromEntries(selection.getAttributes()),
              'src': res
            }
          );
          editor.model.insertObject(externalWidget, null, null, {
            setSelection: 'on'
          });
        })

      }
    });
  }

  refresh() {
    const model = this.editor.model;
    const selection = model.document.selection;

    const isAllowed = model.schema.checkChild(selection.focus.parent, 'uploadVideo');

    this.isEnabled = isAllowed;
  }
}

class ExternalDataWidget extends Plugin {
  static get requires() {
    return [ExternalDataWidgetEditing, ExternalDataWidgetUI];
  }
}

class ExternalDataWidgetUI extends Plugin {
  init() {
    const editor = this.editor;
    const externalWidgetCommand = editor.commands.get('uploadVideo');

    editor.ui.componentFactory.add('uploadVideo', locale => {
      const button = new ButtonView(locale);

      button.set({
        label: '从电脑上传视频',
        tooltip: true,
        withText: false,
        icon: Icon
      });

      // button.bind('isEnabled').to(externalWidgetCommand);

      button.on('execute', () => {
        editor.execute('uploadVideo');
        editor.editing.view.focus();
      });

      return button;
    });
  }
}

class ExternalDataWidgetEditing extends Plugin {

  constructor(editor) {
    super(editor);
    this.externalDataValue = '';
  }

  static get requires() {
    return [Widget];
  }

  destroy() {
    // clearInterval(this.intervalId);
  }

  init() {
    this._defineSchema();
    this._defineConverters();
    this._updateWidgetData();

    this.editor.commands.add('uploadVideo', new ExternalDataWidgetCommand(this.editor));
  }

  _intervalFetch() {
    return setInterval(() => this._updateWidgetData(), 10000); // set time interval to 10s
  }

  async _updateWidgetData(externalUrl = '') {
    try {
      this.externalDataValue = externalUrl;

      const rootElement = this.editor.model.document.getRoot();

      for (const {
          item
        } of this.editor.model.createRangeIn(rootElement)) {
        if (item.is('element', 'uploadVideo')) {
          this.editor.editing.reconvertItem(item);
        }
      }
    } catch (error) {
      console.error(error);
    }
  }

  _defineSchema() {
    const schema = this.editor.model.schema;

    schema.register('uploadVideo', {
      inheritAllFrom: '$inlineObject',
      allowAttributes: ['src', 'controls'],
      extra: {},
    });
  }

  _defineConverters() {
    const editor = this.editor;

    editor.conversion.for('upcast').elementToElement({
      view: {
        name: 'video',
        attributes: ['src', 'controls']
      },
      model: (viewElement, {
        writer
      }) => {
        const externalUrl = viewElement.getAttribute('src');

        return writer.createElement('uploadVideo', {
          'src': externalUrl,
          class: 'uploadVideo-data-widget-phone',
          controls: true,
        });
      }
    });

    editor.conversion.for('dataDowncast').elementToElement({
      model: 'uploadVideo',
      view: (modelElement, {
        writer
      }) => {
        return writer.createEmptyElement('video', {
          'src': modelElement.getAttribute('src'),
          class: 'uploadVideo-data-widget-preview',
          controls: true,
        });
      }
    });
    editor.conversion.for('editingDowncast').elementToElement({
      model: 'uploadVideo',
      view: (modelElement, {
        writer
      }) => {


        const externalDataPreviewElement = writer.createRawElement('video', null, function (domElement) {
          domElement.classList.add('uploadVideo-data-widget');
          domElement.src = modelElement.getAttribute('src');
          domElement.controls = true
        });
        
        const externalWidgetContainer = writer.createContainerElement( 'div', null, externalDataPreviewElement );

        return toWidget( externalWidgetContainer, writer, {
            label: '媒体小部件'
        } );
      }
    });
  }
}

export default ExternalDataWidget